package com.haredot.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.haredot.dto.PermissionTree;
import com.haredot.entity.Role;
import com.haredot.exception.ServiceAccessException;
import com.haredot.mapper.RoleMapper;
import com.haredot.service.RoleService;
import com.haredot.vo.PageVo;
import com.haredot.vo.R;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
@Transactional(rollbackFor = Exception.class)
public class RoleServiceImpl implements RoleService {

    @Resource
    private RoleMapper roleMapper ;

    @Override
    public R<?> saveRole(Role role) {
        // 根据角色名查询角色信息
        Role byRole = roleMapper.findRoleByName(role.getName());

        if (byRole != null) return R.fail(R.StatusCode.BAD).data(Map.of("name", "角色名已经存在"));
        // 根据角色标记查询
        byRole = roleMapper.findRoleByRemark(role.getRemark());

        if (byRole != null) return R.fail(R.StatusCode.BAD).data(Map.of("remark", "角色标识已经存在"));

        // 保存角色信息
        int len = roleMapper.insert(role) ;

        if (len != 1) throw new ServiceAccessException("保存角色失败、期待影响1行、实际影响" + len + "行");

        return R.ok().build();
    }

    @Override
    public R<?> updateRole(Role role) {
        // 根据角色名查询角色信息
        Role byRole = roleMapper.findRoleByName(role.getName());

        if (byRole != null && !Objects.equals(role.getId(), byRole.getId())) {
            return R.fail(R.StatusCode.BAD).data(Map.of("name", "角色名已经存在"));
        }
        // 根据角色标记查询
        byRole = roleMapper.findRoleByRemark(role.getRemark());

        if (byRole != null && !Objects.equals(role.getId(), byRole.getId())){
            return R.fail(R.StatusCode.BAD).data(Map.of("remark", "角色标识已经存在"));
        }

        // 保存角色信息
        int len = roleMapper.update(role) ;

        if (len != 1) throw new ServiceAccessException("修改角色失败、期待影响1行、实际影响" + len + "行");

        return R.ok().build();
    }

    @Override
    public R<?> removeRole(Long id) {
        int len = roleMapper.deleteById(id);

        if (len != 1) throw new ServiceAccessException("删除角色失败、期待影响1行、实际影响" + len + "行");

        return R.ok().build();
    }

    @Override
    public R<?> batchRemoveRoles(List<Long> roleIds) {

        int len = roleMapper.batchDeleteByIds(roleIds);

        if (len != roleIds.size()) throw new ServiceAccessException("批量删除角色失败、期待影响"+ roleIds.size()+"行、实际影响" + len + "行");

        return R.ok().build();
    }

    @Override
    public R<PageVo> queryRolesByPage(PageVo pageVo, Map<String, Object> searchParams) {
        PageInfo<Role> info = PageHelper.startPage(pageVo)
                .doSelectPageInfo(()-> roleMapper.findRolesByCondition(searchParams));

        pageVo.setList(info.getList()).setTotal(info.getTotal());
        return R.<PageVo>ok().data(pageVo);
    }

    @Override
    public R<PermissionTree> queryPermissionTree(Long roleId) {

        List<PermissionTree> treeRefRoleId = roleMapper.findTreeRefRoleId(roleId);

        return R.<PermissionTree>ok().data(treeRefRoleId);
    }

    @Override
    public R<?> bindPermission(Long roleId, List<PermissionTree> nodes) {
        // 先根据 roleId 删除权限表中的权限
        int len  = roleMapper.removePermissionByRoleId(roleId) ;

        // 批量插入 选中的所有权限
        if (!nodes.isEmpty()) {
            roleMapper.batchSavePermission(roleId, nodes);
        }
        return R.ok().build();
    }
}
